Ext.Loader.setConfig({
    enabled: true
});

Ext.application({
    name: 'Employees',
    appFolder: '/Employees/scripts/apps/employees/app',
    controllers: [
        'EmployeeController'
    ],
    launch: function() {
        createUI();
    }
});

function newHttpRequest(callback)
{
    if (window.XMLHttpRequest)
    {
        request = new XMLHttpRequest();
    }
    else
    {
        request = new ActiveXObject("Microsoft.XMLHTTP");
    }
    
    request.onreadystatechange = callback;
    
    return request;
}

function deleteItem(treeView, record)
{
    var url = 'removeObject?id=' + record.get('id');

    if (record.get('department'))
    {
        url += ('&department=true');
    }

    var ajaxRequest = newHttpRequest(function()
    {
        refreshContent(treeView);
    });

    ajaxRequest.open("POST", url, true);
    ajaxRequest.send();
}

function onDepartmentNodeContextMenu(tree, rec, html, index, event)
{
    var menu = Ext.create('Ext.menu.Menu', {
        plain: true,
        floating: true,
        items: [
        {
            text: 'New employee',
            handler: function () {
                onCreateEmployee(rec.get('id'));
            }
        },
        {
            text: 'Delete department',
            handler: function () {
                deleteItem(tree, rec);
            }
        },
        {
            text: 'Rename department',
            handler: function () {
                // TODO
            }
        },
        {
            text: 'Department properties',
            handler: function () {
                showItemProperties(rec, true);
            }
        }]
    });
    menu.showAt(event.getXY());
}

function submitItemJSON(record)
{
    var request = newHttpRequest(new function() {
        onItemSaved();
    });

    request.open('POST', 'saveObject');
    request.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
    request.send(record);
}

function refreshContent(tree)
{
    var store = tree.getTreeStore();

    // Working around this bug:
    // http://www.sencha.com/forum/showthread.php?151211-Reloading-TreeStore-adds-all-records-to-store-getRemovedRecords
    store.getRootNode().removeAll();
    // End of workaround
    store.load({
        callback: function() {
            tree.refresh();
        }
    });
}

function createItemEditor(itemRecord, isDepartment, parentDepartmentId, saveCb, cancelCb)
{
    if (itemRecord == null) {
        itemRecord = Ext.create('Employees.model.Employee');
    }

    var tabs = Ext.create('Ext.tab.Panel', {
        border:false,
        bodyPadding: 5,
        items: [{
            title: 'General',
            xtype: 'panel',
            border: false,
            items: [{
                xtype: 'textfield',
                fieldLabel: 'First Name',
                name: 'firstName',
                allowBlank: false
            },{
                xtype: 'textfield',
                fieldLabel: 'Last Name',
                name: 'lastName',
                allowBlank: false
            }, {
                xtype: 'hiddenfield',
                name: 'id'
            }, {
                xtype: 'hiddenfield',
                name: 'dep_id',
                value: parentDepartmentId
            }]
        }],
        layout: 'fit'
    });

    if (!isDepartment) {
        var contactTab = Ext.create('Ext.panel.Panel', {
            title: 'Contact details',
            xtype: 'panel',
            border: false,
            items: {
                xtype: 'textfield',
                fieldLabel: 'Email',
                name: 'email',
                vtype: 'email'
            },
            layout: 'vbox'
        });
        tabs.add(contactTab);
    }

    var editForm = Ext.create('Ext.form.Panel', {
        width: 350,
        height: 500,
        border: false,
        // The form will submit an AJAX request to this URL when submitted
        url: 'saveObject',
        layout: 'form',
        items: tabs,
        defaultType: 'textfield',
        model: 'OrganizationNode',
        // Reset and Submit buttons
        buttons: [{
            text: 'Save',
            formBind: true, //only enabled once the form is valid
            disabled: true,
            handler: function() {
                var form = this.up('form').getForm();
                if (form.isValid()) {
                    form.submit({
                        success: function() {
                            if (saveCb) {
                                saveCb();    
                            }
                        },
                        failure: function(form, action) {
                            console.log('Failed to add item');
                        }
                    });
                }
            }
        }, {
            text: 'Cancel',
            formBind: false,
            handler: function() {
                if (cancelCb) {
                    cancelCb();
                }
            }
        }]
    });

    editForm.loadRecord(itemRecord);

    return editForm;
}

function showItemProperties(rec, isDepartment, departmentId)
{
    var wndTitle = (rec == null) ? 'New employee' : 'Details: ' + rec.get('text');
    var parentId = (rec == null) ? departmentId : rec.parentNode.get('id');

    var editWnd = Ext.create('Ext.window.Window', {
        title: wndTitle,
        border: false,
        height: 200,
        width: 400,
        modal: true,
        draggable: false,
        layout: 'fit',
        plain: 'true',
        closable: false
    });

    var saveCallback = function() {
        editWnd.close();
    };
    
    var cancelCallback = function() {
        editWnd.close();
    }
    
    var itemEditor = createItemEditor(rec, isDepartment, parentId, saveCallback, cancelCallback);
    
    editWnd.add(itemEditor);

    editWnd.show();
}

function onCreateEmployee(departmentId)
{
    showItemProperties(null, false, departmentId);
}

function onEmployeeNodeContextMenu(tree, rec, html, index, event)
{
    var menu = Ext.create('Ext.menu.Menu', {
        plain: true,
        floating: true,
        items: [
        {
            text: 'Employee properties',
            handler: function () {
                showItemProperties(rec, false);
            }
        },
        {
            text: 'Delete employee',
            handler: function () {
                deleteItem(tree, rec);
            }
        }
        ]
    });
    menu.showAt(event.getXY());
}

function appendChild(parentNode, isLeaf)
{
    parentNode.appendChild({
        text: 'Appended child' + parentNode.childNodes.length,
        leaf: isLeaf
    });
}

function removeSelectedNode()
{
    var selectionModel = tree.getSelectionModel();

    if (selectionModel.hasSelection())
    {
        selectionModel.getSelection()[0].remove(true);
    }
}

function onDepartmentsInfoRetrieved(request)
{
    document.getElementById("test_area").innerHTML = request.responseText;
    
    var departmentList = eval(request.responseText);
    
    console.log("evaluated: " + departmentList);
}

function retrieveDepartments()
{
    var ajaxRequest = newHttpRequest(function() {
        onDepartmentsInfoRetrieved(ajaxRequest);
    });
    ajaxRequest.open("GET", "listDepartments", true);
    ajaxRequest.send();
}

function fillDatabase(tree)
{
    var ajaxRequest = newHttpRequest(null);

    ajaxRequest.open('POST', 'fillDatabase', true);
    ajaxRequest.onreadystatechange = function() {
        refreshContent(tree);
    };
    ajaxRequest.send();
}

function createTreeStore()
{
    var treeStore = Ext.create('Ext.data.TreeStore', {
        model:'Employees.model.OrganizationNode',
        proxy: {
            actionMethods:{
                read: 'GET'
            },
            type: 'ajax',
            url: 'listDepartments',
            reader: {
                type: 'json'
            }
        },
        displayField: 'displayName',
        clearOnLoad: false
    });
    
    treeStore.load();

    return treeStore;
}

function createUI()
{
    Ext.QuickTips.init();

    var tree = Ext.create('Ext.tree.Panel', {
        store: createTreeStore(),
        renderTo: Ext.getBody(),
        height: 500,
        width: 400,
        title: 'Organization structure',
        dockedItems: [{
            xtype: 'toolbar',
            items: [{
                text: 'Retrieve departments',
                handler: function() {
                    retrieveDepartments();
                }
            },
            {
                text: 'Fill database',
                handler: function() {
                    fillDatabase();
                }
            }]
        }],
        displayField: 'displayName'
    });

    tree.on('itemcontextmenu', onItemContextMenu);
}

function onCreateItem(parentNode, isLeaf)
{
    appendChild(parentNode, isLeaf);
}

function onItemContextMenu(view, rec, html, index, event)
{
    event.preventDefault();    

    if (rec.get('isDepartment'))
    {
        onDepartmentNodeContextMenu(view, rec, html, index, event);
    }
    else
    {
        onEmployeeNodeContextMenu(view, rec, html, index, event);
    }
}